`include "../codigo/Forwarding.v"

module test_Forwarding ( ) ;
    reg   t_clock;
    reg   t_reset;

    //Fetch
    wire  t_fw_if_id_stall;

    //Decode
    reg  [4:0]  t_id_fw_regdest;
    reg         t_id_fw_load;
    reg  [4:0]  t_id_fw_addra;
    reg  [4:0]  t_id_fw_addrb;
    reg  [31:0]  t_id_fw_rega;
    reg  [31:0]  t_id_fw_regb;
    wire  [31:0]  t_fw_id_rega;
    wire  [31:0]  t_fw_id_regb;

    //Execute
    reg  [31:0]  t_ex_fw_wbvalue;
    reg          t_ex_fw_writereg;

    //Memory
    reg  [31:0]  t_mem_fw_wbvalue; 
    reg          t_mem_fw_writereg;

    //Writeback
    reg  [31:0]  t_wb_fw_wbvalue;
    reg          t_wb_fw_writereg;

	Forwarding t_forwarding (.clock(t_clock),
		.reset(t_reset),
		.fw_if_id_stall(t_fw_if_id_stall),
		.id_fw_regdest(t_id_fw_regdest),
		.id_fw_load(t_id_fw_load),
        .id_fw_addra(t_id_fw_addra),
		.id_fw_addrb(t_id_fw_addrb),
		.id_fw_rega(t_id_fw_rega),
		.id_fw_regb(t_id_fw_regb),
		.fw_id_rega(t_fw_id_rega),
		.fw_id_regb(t_fw_id_regb),
		.ex_fw_wbvalue(t_ex_fw_wbvalue),
		.ex_fw_writereg(t_ex_fw_writereg),
		.mem_fw_wbvalue(t_mem_fw_wbvalue), 
		.mem_fw_writereg(t_mem_fw_writereg),
		.wb_fw_wbvalue(t_wb_fw_wbvalue),
		.wb_fw_writereg(t_wb_fw_writereg) );

    
	initial begin
	//Teste Reset

	t_reset = #0 1'b0;
	$display("Teste Reset:\nresultado esperado ao fim do teste:\nfw_id_rega = 0\nfw_id_regb = 0\n");		
	t_forwarding.fw_id_rega = #0 32'b1010010;
	t_forwarding.fw_id_regb = #0 32'b10110101;
	$display("Valores Iniciais:\nfw_id_rega = %d\nfw_id_regb = %d\n", t_forwarding.fw_id_rega, t_forwarding.fw_id_regb); 
	t_reset = #2 1'b0;
	t_reset = #2 1'b1;
	t_clock = #0 1'b0;
	t_clock = #2 1'b0;
	$display("Valores Finais:\nfw_id_rega = %d\nfw_id_regb = %d\n", t_forwarding.fw_id_rega, t_forwarding.fw_id_regb);
	//Fim Teste
	
	t_reset = #2 1'b0;
	//Teste Stall
	$display("Teste Para verificar stall:");
	$display("Resultado Esperado:\nfw_if_id_stall = 1\n");
	t_id_fw_regdest = #2 5'b00011;
	t_id_fw_addra = #2 5'b11011;
	t_id_fw_addrb = #2 5'b00000;
	t_id_fw_load = #2 1'b0;
	t_id_fw_load = #2 1'b1;
	t_clock = #2 1'b0;
	t_clock = #2 1'b1;
	t_clock = #2 1'b0;
	t_clock = #2 1'b1;
	t_clock = #2 1'b0;
	t_clock = #2 1'b1;

	$display("Valor Inicial:\nfw_if_id_stall = %d\n", t_forwarding.fw_if_id_stall);
	t_forwarding.TableFW[1] = #2 5'b11011;
	t_id_fw_addra = #2 5'b11011;
	t_id_fw_addrb = #2 5'b00000;
	t_clock = #2 1'b0;
	t_clock = #2 1'b1;
	$display("Valor final:\nfw_if_id_stall = %d\n", t_forwarding.fw_if_id_stall);
	t_forwarding.TableFW[1] = #2 5'b10011;
	t_id_fw_addra = #2 5'b11011;
	t_id_fw_addrb = #2 5'b10011;
	t_clock = #2 1'b0;
	t_clock = #2 1'b1;
	$display("Valor dos registradores alterados, dependencia com o registrador B\nValor Obtido:\nfw_if_id_stall = %d\n", t_forwarding.fw_if_id_stall);
	t_forwarding.TableFW[1] = #2 5'b00011;
	t_id_fw_addra = #2 5'b11011;
	t_id_fw_addrb = #2 5'b10011;
	t_clock = #2 1'b0;
	t_clock = #2 1'b1;
	$display("Valor Sem dependencias, Resultado esperado\n fw_if_id_stall = 0\n Resultado obtido:\nfw_if_id_stall = %d\n", t_forwarding.fw_if_id_stall);
	//Fim teste
	t_reset = #2 1'b0;
	t_reset = #2 1'b1;
	t_reset = #2 1'b0;	

	//Testes Encaminhamentos
	$display("Testes de encaminhamento:\n");
	$display("Teste Para encaminhamento do estágio de execução por prioridade:\n");
	t_ex_fw_writereg = #2 1'b1;
	t_mem_fw_writereg = #2 1'b1;
	t_wb_fw_writereg = #2 1'b1;
	t_forwarding.TableFW[0] = #2 5'b10111;
	
	t_clock = #0 1'b0;
	t_clock = #2 1'b1;

	t_forwarding.TableFW[0] = #2 5'b10101;
	t_clock = #0 1'b0;
	t_clock = #2 1'b1;

	t_forwarding.TableFW[0] = #2 5'b11010;
	t_id_fw_addra = #0 5'b11010;
	t_ex_fw_wbvalue = #2 32'b100;

	t_clock = #0 1'b0;
	t_clock = #2 1'b1;

	t_clock = #2 1'b0;
	t_clock = #2 1'b1;

	t_clock = #2 1'b0;
	t_clock = #2 1'b1;
	$display("Valor esperado:\nfw_id_rega = 4 \nValor obtido:\n fw_id_rega = %d", t_forwarding.fw_id_rega);  

	$display("Teste Para encaminhamento do estágio de memória por prioridade:\n");
	t_ex_fw_writereg = #2 1'b0;
	t_mem_fw_writereg = #2 1'b1;
	t_wb_fw_writereg = #2 1'b1;
	t_forwarding.TableFW[2] = #2 5'b10111;
	
//	t_clock = #0 1'b0;
//	t_clock = #2 1'b1;

	t_forwarding.TableFW[1] = #2 5'b10101;
//	t_clock = #0 1'b0;
//	t_clock = #2 1'b1;

	t_forwarding.TableFW[0] = #2 5'b11010;
	t_id_fw_addra = #0 5'b10101;
	t_mem_fw_wbvalue = #2 32'b110;

	t_clock = #0 1'b0;
	t_clock = #2 1'b1;

	t_clock = #2 1'b0;
	t_clock = #2 1'b1;

	t_clock = #2 1'b0;
	t_clock = #2 1'b1;
	$display("Valor esperado:\nfw_id_rega = 6 \nValor obtido:\n fw_id_rega = %d", t_forwarding.fw_id_rega);  

	$display("Teste Para encaminhamento do estágio de writeback:\n");
	t_ex_fw_writereg = #2 1'b0;
	t_mem_fw_writereg = #2 1'b0;
	t_wb_fw_writereg = #2 1'b1;
	t_forwarding.TableFW[2] = #2 5'b10111;
	t_forwarding.TableFW[1] = #2 5'b10101;
	t_forwarding.TableFW[0] = #2 5'b11010;
	t_id_fw_addra = #0 5'b10111;
	t_wb_fw_wbvalue = #2 32'b101;

	t_clock = #0 1'b0;
	t_clock = #2 1'b1;

	t_clock = #2 1'b0;
	t_clock = #2 1'b1;

	t_clock = #2 1'b0;
	t_clock = #2 1'b1;
	$display("Valor esperado:\nfw_id_rega = 5 \nValor obtido:\n fw_id_rega = %d", t_forwarding.fw_id_rega);  






	end
endmodule
